home *** CD-ROM | disk | FTP | other *** search
/ Carousel / CAROUSEL.cdr / mactosh / code / p_serlib.sit / Serial Library Source Code / serial.waitTilStr.dll.c < prev    next >
C/C++ Source or Header  |  1989-07-27  |  8KB  |  302 lines

  1. /***********************************************************************/
  2. /*    
  3. /*    serial.waitTilStr.dll.c
  4. /*    by Atul Butte
  5. /*    Copyright ⌐ 1989 by Microsoft Corporation
  6. /*    All Rights Reserved
  7. /*
  8. /*    version 1.0
  9. /*    
  10. /*    
  11. /*    This CALL/REGISTER will read from the serial port until the specifed
  12. /*    string is read.
  13. /*    
  14. /*    Excel usage:
  15. /*    
  16. /*    = Register( "serial library", "serial.waitTilStr", "IHDJC" )
  17. /*    = Call( ref, portNumber, matchStr, maxTime, readConfigStr )
  18. /*    
  19. /*    where
  20. /*        portNumber        = number of port (1 = modem, 2 = printer)
  21. /*        matchStr        = keep reading until we read this string
  22. /*        maxTime            = maximum amount of time to wait for characters
  23. /*                          in 1/60 second units
  24. /*        readConfigStr    = configuration of communications protocol, etc
  25. /*    
  26. /***********************************************************************/
  27.  
  28. /***********************************************************************/
  29. /*
  30. /*    D E F I N E S
  31. /*
  32. /***********************************************************************/
  33.  
  34. #define ROUTINE_NAME    "serial.waitTilStr"
  35. #define hNIL 0L
  36. #define pNIL 0L
  37.  
  38. /***********************************************************************/
  39. /*
  40. /*    I N C L U D E S
  41. /*
  42. /***********************************************************************/
  43.  
  44. #include "serial.h"
  45. #include "error.h"
  46. #include "get_port.h"
  47. #include "interpret.h"
  48. #include "get_read_flags.h"
  49.  
  50. /***********************************************************************/
  51. /*
  52. /*    P R O T O T Y P E S
  53. /*
  54. /***********************************************************************/
  55.  
  56. void initialize_next( Ptr pnxt, char *pstMatch );
  57. char check_for_match( char cRead, unsigned char cCurrentChar, unsigned char cMatchLength, char *pstMatch, Ptr pnxt );
  58.  
  59. /***********************************************************************/
  60. /*
  61. /*    main
  62. /*
  63. /***********************************************************************/
  64.  
  65. pascal short main( port, pstMatch, timeDur, pszConfig )
  66.  
  67.     unsigned short            port;                    /* serial port to use */
  68.     char                    *pstMatch;                /* keep reading until we read this string */
  69.     unsigned long            timeDur;                /* maximum time to wait for chars (in ticks) */
  70.     char                    *pszConfig;                /* communications configuration string */
  71.     
  72. {
  73.     register OSErr            err;                    /* result code from Toolbox routines */
  74.     ParamBlockRec            param;                    /* parameter block for read/write */
  75.     
  76.     Boolean                    fEcho = false;            /* flag for echoing characters */
  77.     Boolean                    fEdit = false;            /* flag for allowing edit characters */
  78.     Boolean                    fStripLF = false;        /* flag for stripping line feeds */
  79.     Boolean                    fStrip8Bit = false;        /* flag for stripping high bit */
  80.     Boolean                    fAddLF = false;            /* flag for adding LF after CR */
  81.     Boolean                    fIgnore = false;        /* flag for ignoring escape chars */
  82.     
  83.     Handle                    hnxt;                    /* handle to the next table */
  84.     register Ptr            pnxt;                    /* pointer to the next table */
  85.     long                    cchBuff = 0;            /* number of characters waiting in read buffer */
  86.     register unsigned long    timeStop;                /* time at which to stop */
  87.     short                    refIn;                    /* reference number for input port */
  88.     short                    refOut;                    /* reference number for output port */
  89.     char                    chRead;                    /* buffer used to read a character */
  90.     register char            ch;                        /* character read */
  91.     char                    echoBackspace[3];        /* characters to send to echo Backspace */
  92.     char                    echoLinefeed;            /* characters to send to echo Linefeed */
  93.     register unsigned char    cchMatched;                /* number of characters matching so far */
  94.     register unsigned char    cchMatch;                /* number of characters to match */
  95.     
  96.     RememberA0();
  97.     SetUpA4();
  98.     
  99.     if( pszConfig == pNIL ) {
  100.         display_error( "The fourth parameter must be a configuration string." );
  101.         RestoreA4( );
  102.         return( errParam );
  103.     }
  104.     if( pstMatch == pNIL ) {
  105.         display_error( "The second parameter must be a string to match." );
  106.         RestoreA4( );
  107.         return( errParam );
  108.     }
  109.     if( *pstMatch == 0 ) {
  110.         display_error( "You must specify a string to match with at least one character." );
  111.         RestoreA4( );
  112.         return( errParam );
  113.     }
  114.     
  115.     err = get_port( port, &refIn, &refOut );
  116.     if( err != noErr ) {
  117.         display_error( "Illegal port number." );
  118.         RestoreA4( );
  119.         return( errInvalidPort );
  120.     }
  121.     
  122.     get_read_flags( pszConfig, &fEcho, &fEdit, &fStripLF, &fStrip8Bit, &fAddLF, &fIgnore );
  123.     
  124.     if( !fIgnore ) {
  125.         err = interpret( pstMatch );
  126.         if( err != noErr ) {
  127.             RestoreA4( );
  128.             return( errStrFormat );
  129.         }
  130.     }
  131.  
  132.     cchMatched = 1;
  133.     cchMatch = *pstMatch;
  134.     if( cchMatch > 1 ) {
  135.         hnxt = NewHandle( (long) *pstMatch + 1 );
  136.         HLock( hnxt );
  137.         pnxt = *hnxt;
  138.         initialize_next( pnxt, pstMatch );
  139.     }
  140.  
  141.     if( fEcho ) {
  142.         echoBackspace[0] = kchBackspace;
  143.         echoBackspace[1] = ' ';
  144.         echoBackspace[2] = kchBackspace;
  145.         if( fAddLF ) {
  146.             echoLinefeed = kchLinefeed;
  147.         }
  148.     }
  149.     
  150.     timeStop = TickCount( ) + timeDur;
  151.     
  152.     while( true ) {
  153.         if( ( timeDur != 0 ) && ( TickCount( ) >= timeStop ) ) {
  154.             break;
  155.         }
  156.         err = SerGetBuf( refIn, &cchBuff );
  157.         if( err != noErr ) {
  158.             display_error( "Error trying to count buffer." );
  159.             err = errSerialGetBuf;
  160.             goto CleanExit;
  161.         }
  162.         if( cchBuff == 0 )
  163.             continue;
  164.         
  165.         param.ioParam.ioReqCount = 1;
  166.         param.ioParam.ioBuffer = &chRead;
  167.         param.ioParam.ioRefNum = refIn;
  168.         err = PBRead( ¶m, false );
  169.         if( err != noErr ) {
  170.             display_error( "Error reading from serial port." );
  171.             err = errSerialRead;
  172.             goto CleanExit;
  173.         }
  174.         ch = chRead;
  175.         
  176.         if( ( (ch == kchBackspace) || (ch == kchDelete) ) && (fEdit) ) {
  177.             if( fEcho ) {
  178.                 param.ioParam.ioReqCount = 3;
  179.                 param.ioParam.ioRefNum = refOut;
  180.                 param.ioParam.ioBuffer = echoBackspace;
  181.                 err = PBWrite( ¶m, false );
  182.                 if( err != noErr ) {
  183.                     display_error( "Error echoing backspace to serial port." );
  184.                     err = errSerialWrite;
  185.                     goto CleanExit;
  186.                 }
  187.             }
  188.         } else if( fEcho ) {
  189.             param.ioParam.ioReqCount = 1;
  190.             param.ioParam.ioRefNum = refOut;
  191.             param.ioParam.ioBuffer = &chRead;
  192.             err = PBWrite( ¶m, false );
  193.             if( err != noErr ) {
  194.                 display_error( "Error echoing to serial port." );
  195.                 err = errSerialWrite;
  196.                 goto CleanExit;
  197.             }
  198.             if( (ch == kchReturn) && (fAddLF) ) {
  199.                 param.ioParam.ioReqCount = 1;
  200.                 param.ioParam.ioRefNum = refOut;
  201.                 param.ioParam.ioBuffer = &echoLinefeed;
  202.                 err = PBWrite( ¶m, false );
  203.                 if( err != noErr ) {
  204.                     display_error( "Error echoing linefeed to serial port." );
  205.                     err = errSerialWrite;
  206.                     goto CleanExit;
  207.                 }
  208.             }
  209.         }
  210.         
  211.         if( fStrip8Bit ) {
  212.             ch &= 0x7F;
  213.         }
  214.         
  215.         if( (ch == kchLinefeed) && (fStripLF) ) {
  216.         } else {
  217.             cchMatched = check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt );
  218.             if( cchMatched > cchMatch ) /* if we found a match */
  219.                 break;
  220.         }
  221.     }
  222.     
  223.     if( cchMatched > cchMatch ) {
  224.         err = noErr;
  225.     } else {
  226.         err = errTimeOut;
  227.     }
  228.     
  229. CleanExit:
  230.  
  231.     if( cchMatch > 1 )
  232.         DisposHandle( hnxt );
  233.     RestoreA4();
  234.     return( err );
  235. }
  236.  
  237. /***********************************************************************/
  238. /*
  239. /*    initialize_next
  240. /*
  241. /***********************************************************************/
  242.  
  243. void initialize_next( pnxt, pstMatch )
  244.  
  245.     register Ptr            pnxt;                    /* pointer to the next table */
  246.     char                    *pstMatch;                /* keep reading until we read this string */
  247.     
  248. {
  249.     register unsigned long    i = 1, j = 0;            /* index through match string */
  250.     register unsigned char    cchMatch = *pstMatch;    /* number of characters to match */
  251.     
  252.     pnxt[1] = 0;
  253.     do {
  254.         if( ( j == 0 ) || ( pstMatch[i] == pstMatch[j] ) ) {
  255.             i++;
  256.             j++;
  257.             pnxt[i] = j;
  258.         } else {
  259.             j = pnxt[j];
  260.         }
  261.     } while( i <= cchMatch );
  262. }
  263.  
  264. /***********************************************************************/
  265. /*
  266. /*    check_for_match
  267. /*
  268. /***********************************************************************/
  269.  
  270. char check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt )
  271.  
  272.     register char            ch;                        /* character read */
  273.     register unsigned char    cchMatched;                /* number of characters matching so far */
  274.     register unsigned char    cchMatch;                /* number of characters to match */
  275.     char                    *pstMatch;                /* keep reading until we read this string */
  276.     register Ptr            pnxt;                    /* pointer to the next table */
  277.     
  278. {
  279.     if( cchMatch == 1 ) {
  280.         if( ch == pstMatch[1] ) {
  281.             return( 2 );
  282.         } else {
  283.             return( 1 );
  284.         }
  285.     } else {
  286.         do {
  287.             if( ( cchMatched == 0 ) || ( ch == pstMatch[cchMatched] ) ) {
  288.                 cchMatched++;
  289.                 break;
  290.             } else {
  291.                 cchMatched = pnxt[cchMatched];
  292.             }
  293.         } while( cchMatched <= cchMatch );
  294.         
  295.         return( cchMatched );
  296.     }
  297. }
  298.  
  299. #include "get_port.c"
  300. #include "interpret.c"
  301. #include "get_read_flags.c"
  302.